-
Notifications
You must be signed in to change notification settings - Fork 8
refactor: CD 성능 개선 #552
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor: CD 성능 개선 #552
Conversation
Walkthrough1. GitHub Actions 워크플로우 전환. Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes
Suggested reviewers
Pre-merge checks and finishing touches✅ Passed checks (5 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (2)
🧰 Additional context used🧠 Learnings (1)📚 Learning: 2025-11-10T01:55:03.827ZApplied to files:
🔇 Additional comments (13)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Nitpick comments (2)
.github/workflows/prod-cd.yml (1)
82-130: 원격 배포 SSH 스크립트의 복원력 개선이 필요합니다.현재 SSH 스크립트는 여러 단계를 순차적으로 실행하며
set -e로 에러 시 중단하도록 설정되어 있습니다. 그러나 다음과 같은 시나리오에서 개선이 필요합니다:상황별 개선 사항:
docker pull 실패 시 처리
- 현재: 에러 발생 시 그냥 중단
- 제안: 기존 이미지로 서비스 유지 또는 명확한 실패 알림
docker compose up -d 실패 시 처리
- Line 123에서 새 컨테이너 시작 실패 시, 이전 컨테이너가 이미 down된 상태
- 제안: 스크린샷 또는 파일로 이전 상태 백업 후 롤백 가능하도록 개선
Nginx 설정 적용 실패 시 처리
- Line 111의 nginx -t 검증 후 reload가 실패하면 서비스 불가
- 제안: 구 설정 백업 후 검증 실패 시 복구
아래와 같이 개선하는 것을 권장합니다:
# Nginx 설정 변경 전 백업 cp /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.backup # 새 설정 적용 sudo cp ./nginx/default.conf /etc/nginx/conf.d/default.conf # 검증 실패 시 복구 if ! sudo nginx -t; then echo "Nginx configuration test failed. Reverting..." sudo cp /etc/nginx/conf.d/default.conf.backup /etc/nginx/conf.d/default.conf sudo nginx -t exit 1 fi sudo nginx -s reload또한 Docker Compose도 이전 상태 보존을 고려하세요:
# 이전 상태 백업 docker compose -f docker-compose.prod.yml cp solid-connection-server:/var/log/spring ./logs.backup # 새 버전으로 재시작 OWNER_LOWERCASE=$OWNER_LOWERCASE IMAGE_TAG=$IMAGE_TAG_ONLY docker compose -f docker-compose.prod.yml up -d # 헬스 체크 (옵션) sleep 5 curl -f http://localhost:8080/health || { echo "Health check failed"; exit 1; }.github/workflows/dev-cd.yml (1)
118-119: Docker Compose 정리 명령어가 prod 워크플로우와 불일치합니다.현재 dev-cd.yml:
- Line 118:
docker compose -f docker-compose.dev.yml downprod-cd.yml (더 견고함):
- Line 117-120:
docker compose ... stop(graceful shutdown)docker compose ... down --remove-orphans(고아 네트워크/볼륨 정리)차이점:
- prod는 명시적으로 stop → down 순서 진행
- prod는
--remove-orphans플래그 사용 (고아 리소스 제거)- dev는 이 두 가지를 누락
이로 인해 dev 환경에서 장기 실행 후 불필요한 네트워크/볼륨이 쌓일 수 있습니다.
prod 워크플로우와 일치하도록 수정하세요:
# 6. Docker Compose 재시작 echo "Restarting Docker Compose with tag: $IMAGE_TAG_ONLY" - docker compose -f docker-compose.dev.yml down + echo "Stopping containers gracefully..." + docker compose -f docker-compose.dev.yml stop + + echo "Removing old containers and networks..." + docker compose -f docker-compose.dev.yml down --remove-orphans + + echo "Starting new containers..." OWNER_LOWERCASE=$OWNER_LOWERCASE IMAGE_TAG=$IMAGE_TAG_ONLY docker compose -f docker-compose.dev.yml up -d
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
.github/workflows/dev-cd.yml(2 hunks).github/workflows/prod-cd.yml(1 hunks)Dockerfile(2 hunks)docker-compose.dev.yml(2 hunks)docker-compose.prod.yml(1 hunks)src/main/resources/secret(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-25T10:59:42.734Z
Learnt from: whqtker
Repo: solid-connection/solid-connect-server PR: 481
File: docs/infra-config/nginx.conf:36-36
Timestamp: 2025-08-25T10:59:42.734Z
Learning: When using network_mode: host in Docker Compose, containers share the host's network namespace, so nginx proxy_pass should target localhost:PORT instead of container service names like solid-connection-server:PORT.
Applied to files:
docker-compose.prod.yml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (6)
src/main/resources/secret (1)
1-1: 서브모듈 포인터 업데이트 확인 필요합니다.
src/main/resources/secret서브모듈이ae3e90ef→b2fb5167로 업데이트되었습니다. 다음 사항을 확인해 주세요:
- 변경 내용 검증: 새 커밋 (
b2fb5167)에서 어떤 변경사항이 발생했는지 확인 필요- CD 리팩터링 연관성: 현재 PR의 CD 워크플로우 개선(GitHub Actions → GHCR → docker-compose)과 이 서브모듈 업데이트의 관계 확인
- 보안 영향도:
secret디렉토리 특성상 민감한 정보 포함 여부 및 변경에 따른 보안 영향 검토이 서브모듈이 실제로 이 PR의 범위에 포함되어야 하는지, 아니면 별도로 관리되어야 하는지 명확히 해 주시기 바랍니다.
docker-compose.dev.yml (1)
21-21: 환경 변수 전달 방식 확인이 필요합니다.Line 21의 이미지 참조가
OWNER_LOWERCASE와IMAGE_TAG환경 변수에 의존하고 있습니다. 워크플로우에서OWNER_LOWERCASE=$OWNER_LOWERCASE IMAGE_TAG=$IMAGE_TAG_ONLY docker compose로 명시적으로 전달하고 있으므로 동작하겠지만, 로컬 개발 환경에서도 이 변수들을 설정하고 실행해야 합니다.로컬에서 수동 테스트 시 아래 명령어로 실행되는지 확인하세요:
export OWNER_LOWERCASE=<your-org> export IMAGE_TAG=<tag-or-leave-for-latest> docker compose -f docker-compose.dev.yml up -ddocker-compose.prod.yml (1)
21-21: 환경 변수 전달 방식 일관성 유지 필요합니다.docker-compose.dev.yml과 마찬가지로 Line 21의 이미지 참조는
OWNER_LOWERCASE와IMAGE_TAG환경 변수에 의존합니다. 워크플로우에서 올바르게 전달되고 있으나, 배포 전 로컬 테스트 시에도 동일한 방식으로 환경 변수를 설정해야 합니다.추가적으로, nginx 설정(prod-cd.yml의 라인 107~112)이 이 compose 파일 외부에서 관리되므로, nginx 컨테이너가 bridge network을 사용하는 경우
proxy_pass http://solid-connection-server:8080형식으로 서비스명을 사용해야 함을 확인하세요.Dockerfile (1)
2-2: Base image 변경이 적절합니다.OpenJDK는 더 이상 유지보수되지 않으며, Eclipse Temurin은 공식 대체 이미지입니다. 변경 자체는 명확하고 문제없어 보입니다.
다만 한 가지 검증 항목:
- 빌드 플랫폼 호환성: 워크플로우에서
linux/arm64플랫폼을 지정하고 있습니다. Eclipse Temurin:17-jdk가 이 플랫폼에서 정상 작동하는지 확인하세요..github/workflows/prod-cd.yml (1)
106-112: Nginx 설정 변경 시 권한 문제 검토가 필요합니다.원격 SSH 명령어에서 Nginx 설정을 다음과 같이 처리하고 있습니다:
- 로컬에서 nginx.prod.conf를 scp로 전송 (Line 76)
- 원격에서 ./nginx/default.conf로 이동 (Line 107)
- sudo로 /etc/nginx/conf.d/default.conf에 복사 (Line 110)
- sudo nginx -t 및 sudo nginx -s reload 실행 (Lines 111-112)
문제점:
sudo명령어 실행 시 비밀번호 입력 없이 동작해야 하는데, 배포 키 기반 SSH에서 이것이 보장되는지 확인 필요- Nginx 설정 검증 실패 시 에러 처리 미흡 (set -e가 있으므로 중단되지만, 롤백 로직 없음)
다음을 확인하세요:
- 배포 서버의 sudoers 파일에서 해당 사용자(
${{ secrets.USERNAME }})가 비밀번호 없이 nginx 명령어를 실행할 수 있도록 설정되었는지 확인- nginx -t 검증 실패 시 이전 설정으로 복구하는 로직 추가 검토
.github/workflows/dev-cd.yml (1)
130-139: 이미지 보관 정책의 이미지명을 검토하세요.Line 134에서
image-names: solid-connection로 지정되어 있으나, 실제 푸시된 이미지명은:
- Line 54:
ghcr.io/${OWNER_LOWERCASE}/solid-connection-dev또한 prod-cd.yml의 보관 정책과도 불일치:
- prod:
image-names: solid-connection-prod- dev:
image-names: solid-connection다음을 확인하고 수정하세요:
- 실제 GHCR에 푸시되는 이미지명 확인
- 보관 정책의 이미지명을 정확하게 매칭:
- image-names: solid-connection + image-names: solid-connection-dev또는 조직 수준의 보관 정책을 사용하려면 와일드카드 지원 여부 확인 필요.
.github/workflows/dev-cd.yml
Outdated
| export FULL_IMAGE_NAME="ghcr.io/${OWNER_LOWERCASE}/solid-connection-dev:${IMAGE_TAG_ONLY}" | ||
| # 2. 서버가 GHCR에 로그인 (pull 받기 위해) | ||
| echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.repository_owner }} --password-stdin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GHCR 로그인 시 사용자명 대소문자 불일치 문제가 있습니다.
dev-cd.yml도 prod-cd.yml과 동일한 문제가 있습니다.
Line 100에서 docker login 시 사용자명으로 ${{ github.repository_owner }}를 사용하고 있으나, 이미지 태그는 소문자로 변환되어 있습니다:
- Line 52:
OWNER_LOWERCASE=$(echo ... | tr '[:upper:]' '[:lower:]') - Line 54: 이미지명에 OWNER_LOWERCASE 사용
GitHub 저장소 소유자명에 대문자가 있으면 로그인 실패 또는 권한 오류 발생 가능성이 있습니다.
수정 방법:
# 2. 서버가 GHCR에 로그인 (pull 받기 위해)
- echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.repository_owner }} --password-stdin
+ OWNER_LOWERCASE=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]')
+ echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${OWNER_LOWERCASE} --password-stdin📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.repository_owner }} --password-stdin | |
| OWNER_LOWERCASE=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]') | |
| echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${OWNER_LOWERCASE} --password-stdin |
🤖 Prompt for AI Agents
.github/workflows/dev-cd.yml around line 100: the docker login uses ${{
github.repository_owner }} which may contain uppercase letters while the image
tag and OWNER_LOWERCASE are used elsewhere, causing GHCR auth failures; change
the login username to the already-computed OWNER_LOWERCASE variable (or compute
a lowercase owner just before login) so the docker login user matches the
lowercase image namespace, and apply the same change in prod-cd.yml.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이전에 lower_case로 통일하도록 이미지 메타데이터 정의 스텝에서 전처리를 해두었기에 문제가 나지 않을 것 같은데?
심지어 내 닉네임이 Hexeong인데, fork 레포에서 깃헙 액션을 실행시켰을 때에 문제가 발생하지 않았었어
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
맞습니다! 제가 잘못 지적했네요. 죄송합니다. 🙇
-
Docker/GHCR 로그인은 사용자명 대소문자를 구분하지 않습니다.
- Line 100의
docker login ghcr.io -u ${{ github.repository_owner }}는Hexeong이든hexeong이든 정상적으로 인증됩니다.
- Line 100의
-
이미지 경로는 올바르게 소문자를 사용하고 있습니다.
- Line 95에서
OWNER_LOWERCASE를 재계산하고 - Line 97에서
FULL_IMAGE_NAME에 소문자 버전을 사용하여 - Line 103의
docker pull이 정상 작동합니다.
- Line 95에서
실제 테스트에서 문제가 없었다는 것이 이를 증명하네요. 불필요한 수정 제안을 드려 혼란을 드려 죄송합니다!
| - name: Log in to GitHub Container Registry (GHCR) | ||
| uses: docker/login-action@v3 | ||
| with: | ||
| registry: ghcr.io | ||
| username: ${{ github.repository_owner }} | ||
| password: ${{ secrets.GITHUB_TOKEN }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GHCR 로그인 시 사용자명 대소문자 불일치 문제가 있습니다.
워크플로우를 자세히 보면:
- GitHub Actions에서 GHCR 로그인 (Line 44):
${{ github.repository_owner }}(원본 대소문자 유지) - 이미지 메타데이터 정의 (Lines 51-54):
OWNER_LOWERCASE=$(echo ... | tr '[:upper:]' '[:lower:]')로 소문자 변환 - 원격 서버 GHCR 로그인 (Line 98):
${{ github.repository_owner }}(원본 대소문자 유지)
문제: GitHub 저장소 소유자명이 대문자를 포함하면, docker pull 시 이미지명과 로그인 사용자명의 대소문자 불일치로 인증 오류가 발생할 수 있습니다.
아래와 같이 수정하세요:
# 2. 서버가 GHCR에 로그인 (pull 받기 위해)
- echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.repository_owner }} --password-stdin
+ OWNER_LOWERCASE=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]')
+ echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${OWNER_LOWERCASE} --password-stdinAlso applies to: 98-100
🤖 Prompt for AI Agents
.github/workflows/prod-cd.yml lines 40-45 (also applies to lines 98-100): GHCR
login uses `${{ github.repository_owner }}` which can contain uppercase letters
causing mismatch with the image names that are converted to lowercase; update
the workflow to pass a lowercased owner username to docker/login-action (use the
same lowercase transformation used for OWNER_LOWERCASE) so both GHCR login steps
use the lowercase repository owner; ensure the environment variable or step
output holding the lowercase owner is referenced in both login steps.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
레지스트리 경로명은 항상 소문자로 유지되기에 repository_owner가 대문자가 포함되어 있어도 이후에 문제가 되지 않아!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Hexeong, 설명 감사합니다! GHCR의 인증 과정에서 사용자명은 대소문자를 구분하지 않고, 레지스트리 경로는 자동으로 소문자로 정규화되는 점을 확인해주셨네요. 제가 너무 신중하게 접근했습니다. 현재 구현이 문제없이 작동하겠네요! 👍
✏️ Learnings added
Learnt from: Hexeong
Repo: solid-connection/solid-connect-server PR: 552
File: .github/workflows/prod-cd.yml:40-45
Timestamp: 2025-11-10T01:55:03.812Z
Learning: GHCR (GitHub Container Registry)에서는 docker login 시 사용자명의 대소문자를 구분하지 않으며, 레지스트리 경로명은 항상 소문자로 정규화됩니다. 따라서 `github.repository_owner`를 그대로 사용해도 이미지 경로와의 대소문자 불일치 문제가 발생하지 않습니다.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
| - name: Clean up old image versions from GHCR | ||
| if: success() | ||
| uses: snok/container-retention-policy@v2 | ||
| with: | ||
| token: ${{ secrets.GITHUB_TOKEN }} | ||
| image-names: solid-connection-prod | ||
| delete-untagged: true | ||
| keep-n-tags: 5 | ||
| account-type: org | ||
| org-name: ${{ github.repository_owner }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이미지 보관 정책의 이미지명 불일치가 있습니다.
Line 138에서 image-names: solid-connection-prod로 지정되어 있으나, 실제 푸시된 이미지는:
- Line 53:
ghcr.io/${OWNER_LOWERCASE}/solid-connection-server
동일하게 dev-cd.yml (Line 134)는 image-names: solid-connection로 지정되어 있습니다.
두 워크플로우 간 네이밍 정책이 일관되지 않습니다. 정리해야 할 항목:
- prod 워크플로우:
solid-connection-prodvs 실제 푸시 이미지명solid-connection-server - dev 워크플로우:
solid-connectionvs 실제 푸시 이미지명solid-connection-dev
이미지 보관 정책이 정확한 이미지명과 일치하도록 수정하세요:
- name: Clean up old image versions from GHCR
...
with:
token: ${{ secrets.GITHUB_TOKEN }}
- image-names: solid-connection-prod
+ image-names: solid-connection-server
delete-untagged: true
keep-n-tags: 5
account-type: org
org-name: ${{ github.repository_owner }}
cut-off: '7 days ago UTC'📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - name: Clean up old image versions from GHCR | |
| if: success() | |
| uses: snok/container-retention-policy@v2 | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| image-names: solid-connection-prod | |
| delete-untagged: true | |
| keep-n-tags: 5 | |
| account-type: org | |
| org-name: ${{ github.repository_owner }} | |
| - name: Clean up old image versions from GHCR | |
| if: success() | |
| uses: snok/container-retention-policy@v2 | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| image-names: solid-connection-server | |
| delete-untagged: true | |
| keep-n-tags: 5 | |
| account-type: org | |
| org-name: ${{ github.repository_owner }} |
🤖 Prompt for AI Agents
In .github/workflows/prod-cd.yml around lines 133-142 the image-names value is
set to "solid-connection-prod" but the pushed image is
"ghcr.io/${OWNER_LOWERCASE}/solid-connection-server" (see push at line 53);
update image-names to "solid-connection-server". Also update the dev workflow
(.github/workflows/dev-cd.yml around line 134) where image-names is
"solid-connection" to the actual pushed name "solid-connection-dev". Ensure the
container-retention-policy steps in both workflows use the exact image names
that are pushed to GHCR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@coderabbitai 해당 내용 반영했어!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gyuhyeok99
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
하지만, prod의 경우 release 버전으로 이미지가 관리될 수 있다 보니, 이미지 태그에 대한 내용을 스크립트 상에 하드코딩할 수 없는 상태입니다.
이게 어떤 말씀이신가요~?? release tag 활용하면 되는 건 아닌가요!?
.github/workflows/prod-cd.yml
Outdated
| sudo nginx -t | ||
| sudo nginx -s reload | ||
| scp -i deploy_key.pem \ | ||
| -o StrictHostKeyChecking:no \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@coderabbitai
StrictHostKeyChecking:no
StrictHostKeyChecking=no
이거 문법 뭐가 맞아?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
올바른 문법은 StrictHostKeyChecking=no 입니다 (등호 사용).
SSH 옵션은 -o option=value 형식을 사용해야 합니다. 콜론(:)이 아니라 등호(=)를 사용해야 합니다.
현재 파일에서 두 곳 모두 수정이 필요합니다:
-
Line 71 (scp 명령어):
scp -i deploy_key.pem \ -o StrictHostKeyChecking=no \
-
Line 83 (ssh 명령어):
ssh -i deploy_key_ssh.pem \ -o StrictHostKeyChecking=no \
콜론을 사용하면 SSH가 옵션을 올바르게 인식하지 못할 수 있습니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
반영했습니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!
아하 제가 릴리즈 기능을 써본 적이 없어서 몰랐던 것 같습니다;; 이 방식으로 배포할 경우 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (2)
.github/workflows/prod-cd.yml (2)
40-45:⚠️ GHCR 로그인 시 소유자명 대소문자 불일치 문제 (이전 리뷰의 미해결 항목)앞선 리뷰에서 지적되었던 문제가 여전히 남아 있습니다.
문제:
- Line 44의 GHCR 로그인:
${{ github.repository_owner }}(원본 대소문자 유지)- Line 53의 이미지명:
ghcr.io/${OWNER_LOWERCASE}/solid-connection-server(소문자 변환)리포지토리 소유자명에 대문자가 포함되면, 로그인 사용자명과 이미지명의 대소문자 불일치로 인증 오류가 발생합니다.
수정:
- name: Log in to GitHub Container Registry (GHCR) uses: docker/login-action@v3 with: registry: ghcr.io - username: ${{ github.repository_owner }} + username: ${{ steps.image_meta.outputs.owner_lowercase }} password: ${{ secrets.GITHUB_TOKEN }}그리고 Line 48-54의 메타데이터 정의 단계에 다음 줄을 추가하세요:
- name: Define image name and tag id: image_meta run: | OWNER_LOWERCASE=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]') + echo "owner_lowercase=${OWNER_LOWERCASE}" >> $GITHUB_OUTPUT IMAGE_TAG=$(date +'%Y%m%d-%H%M%S') echo "image_name=ghcr.io/${OWNER_LOWERCASE}/solid-connection-server" >> $GITHUB_OUTPUT echo "image_tag=${IMAGE_TAG}" >> $GITHUB_OUTPUT
98-98:⚠️ 원격 서버의 GHCR 로그인에서도 소유자명 대소문자 불일치 (이전 리뷰의 미해결 항목)Line 40-45의 GHCR 로그인 문제와 동일하게, 원격 서버에서의 docker login 명령어에서도 대소문자 불일치가 발생합니다.
문제:
- Line 93:
export OWNER_LOWERCASE=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]')로 소문자 변수 생성- Line 98:
docker login ghcr.io -u ${{ github.repository_owner }}(원본 대소문자 사용)변수가 정의되었으므로 일관성 있게 사용하세요.
수정:
# 2. 서버가 GHCR에 로그인 (pull 받기 위해) - echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.repository_owner }} --password-stdin + echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${OWNER_LOWERCASE} --password-stdin
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
.github/workflows/prod-cd.yml(1 hunks)
🔇 Additional comments (4)
.github/workflows/prod-cd.yml (4)
1-34: 기본 설정 단계가 잘 구성되었습니다.Java, Gradle 설정과 초기 빌드 단계가 명확하게 작성되었습니다. 특히 submodule 체크아웃과 Gradle wrapper 권한 설정이 적절합니다.
56-65: Docker 빌드 및 푸시 구성이 잘 설계되었습니다.메타데이터를 올바르게 활용하고, 레지스트리 캐시를 통해 빌드 성능 최적화를 구현한 점이 좋습니다. 멀티 플랫폼 지원도 명시되어 있습니다.
100-130: 배포 로직이 견고하게 구성되었습니다.이미지 pull부터 Nginx 재시작, Docker Compose 재시작, 정리까지의 단계가 명확하고,
set -e를 통한 에러 처리와 graceful shutdown 로직이 좋습니다. 위의 문법 오류들을 수정하면 배포 흐름이 안정적으로 작동할 것입니다.
132-143: GHCR 이미지 정리 정책이 올바르게 수정되었습니다. ✅이전 리뷰에서 지적했던 image-names 불일치 문제(solid-connection-prod → solid-connection-server)가 이미 반영되었습니다. 실제 푸시된 이미지명과 일치하며, 5개 태그 유지 및 7일 이상 된 이미지 정리 정책이 적절합니다.
Gyuhyeok99
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이미지를 pull하는 방식으로 잘 개선해주신 거 같네요! 고생하셨습니다!
길게 잡고 점진적으로 개선해나가봐요!
.github/workflows/dev-cd.yml
Outdated
| keep-n-tags: 5 | ||
| account-type: org | ||
| org-name: ${{ github.repository_owner }} | ||
| cut-off: '7 days ago UTC' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
개행 하나 부탁드려요~
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
반영했습니다!
.github/workflows/prod-cd.yml
Outdated
| keep-n-tags: 5 | ||
| account-type: org | ||
| org-name: ${{ github.repository_owner }} | ||
| cut-off: '7 days ago UTC' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
여기도요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
반영했습니다!
Dockerfile
Outdated
|
|
||
| # 볼륨 설정 | ||
| VOLUME /tmp | ||
| VOLUME /tmp |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
개행!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
반영했습니다!
docker-compose.dev.yml
Outdated
| - ./docs/infra-config/config.alloy:/etc/alloy/config.alloy:ro | ||
| environment: | ||
| - ALLOY_ENV=dev | ||
| - ALLOY_ENV=dev |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
개행!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
반영했습니다!
whqtker
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| - name: Define image name and tag | ||
| id: image_meta | ||
| run: | | ||
| OWNER_LOWERCASE=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
github.repository_owner 로 설정하면 레포 소유자 이름(e.g. whqtker)으로 고정되는 건가요 ? 만약 그렇다면, solid-connection 과 같이 사용자에 종속되지 않는 이름으로 설정하는 게 좋을 거 같습니다 !
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Organization에 속한 레포의 워크플로우 실행의 경우 github.repository_owner은 Organization 이름인 solid-connection이 됩니다! 때문에 사용자 이름으로 종속되지는 않아 해당 문제는 없을 것 같아요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
확인했습니다 ~!
.github/workflows/dev-cd.yml
Outdated
| uses: snok/container-retention-policy@v2 | ||
| with: | ||
| token: ${{ secrets.GITHUB_TOKEN }} | ||
| image-names: solid-connection |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
image-names 를 solid-connection-dev 로 설정해야 할 듯 합니다 ~!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
반영했습니다!
어 그럼 이부분도 GHCR Clean up 작업처럼 하나 추가해서 최신 이미지 10개만 유지하게 할까요?? 어떻게 생각하시나용 @whqtker |
Gyuhyeok99
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이번 pr만큼은 수연님도 리뷰해주시면 좋겠습니다~
Hexeong
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
반영사항들 반영해두었습니다! pending 처리되어있던 걸 제가 늦게 확인했네요;; 빠르게 stage 인스턴스에 대해서도 old 이미지를 지우는 step도 추가해두겠습니다!
.github/workflows/dev-cd.yml
Outdated
| export FULL_IMAGE_NAME="ghcr.io/${OWNER_LOWERCASE}/solid-connection-dev:${IMAGE_TAG_ONLY}" | ||
| # 2. 서버가 GHCR에 로그인 (pull 받기 위해) | ||
| echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.repository_owner }} --password-stdin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이전에 lower_case로 통일하도록 이미지 메타데이터 정의 스텝에서 전처리를 해두었기에 문제가 나지 않을 것 같은데?
심지어 내 닉네임이 Hexeong인데, fork 레포에서 깃헙 액션을 실행시켰을 때에 문제가 발생하지 않았었어
| - name: Clean up old image versions from GHCR | ||
| if: success() | ||
| uses: snok/container-retention-policy@v2 | ||
| with: | ||
| token: ${{ secrets.GITHUB_TOKEN }} | ||
| image-names: solid-connection-prod | ||
| delete-untagged: true | ||
| keep-n-tags: 5 | ||
| account-type: org | ||
| org-name: ${{ github.repository_owner }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@coderabbitai 해당 내용 반영했어!
| - name: Log in to GitHub Container Registry (GHCR) | ||
| uses: docker/login-action@v3 | ||
| with: | ||
| registry: ghcr.io | ||
| username: ${{ github.repository_owner }} | ||
| password: ${{ secrets.GITHUB_TOKEN }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
레지스트리 경로명은 항상 소문자로 유지되기에 repository_owner가 대문자가 포함되어 있어도 이후에 문제가 되지 않아!
.github/workflows/prod-cd.yml
Outdated
| sudo nginx -t | ||
| sudo nginx -s reload | ||
| scp -i deploy_key.pem \ | ||
| -o StrictHostKeyChecking:no \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
반영했습니다!
| - name: Define image name and tag | ||
| id: image_meta | ||
| run: | | ||
| OWNER_LOWERCASE=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Organization에 속한 레포의 워크플로우 실행의 경우 github.repository_owner은 Organization 이름인 solid-connection이 됩니다! 때문에 사용자 이름으로 종속되지는 않아 해당 문제는 없을 것 같아요!
.github/workflows/prod-cd.yml
Outdated
| keep-n-tags: 5 | ||
| account-type: org | ||
| org-name: ${{ github.repository_owner }} | ||
| cut-off: '7 days ago UTC' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
반영했습니다!
Dockerfile
Outdated
|
|
||
| # 볼륨 설정 | ||
| VOLUME /tmp | ||
| VOLUME /tmp |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
반영했습니다!
docker-compose.dev.yml
Outdated
| - ./docs/infra-config/config.alloy:/etc/alloy/config.alloy:ro | ||
| environment: | ||
| - ALLOY_ENV=dev | ||
| - ALLOY_ENV=dev |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
반영했습니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (3)
.github/workflows/dev-cd.yml (3)
69-80: SCP 전송 시 에러 처리 추가 권장.현재 설정 파일 전송 단계에서 scp 명령이 실패해도 워크플로우가 계속 진행됩니다. 예를 들어, 파일이 존재하지 않거나 네트워크 오류가 발생할 경우를 대비하세요.
다음과 같이 개선하면 실패 시 명확히 감지할 수 있습니다:
- name: Copy config files to remote run: | echo "${{ secrets.DEV_PRIVATE_KEY }}" > deploy_key.pem chmod 600 deploy_key.pem + set -e # 에러 발생 시 즉시 중단 + scp -i deploy_key.pem \ -o StrictHostKeyChecking=no \ ./docker-compose.dev.yml \ ./docs/infra-config/config.alloy \ ./docs/infra-config/nginx.dev.conf \ ${{ secrets.DEV_USERNAME }}@${{ secrets.DEV_HOST }}:/home/${{ secrets.DEV_USERNAME }}/solid-connection-dev/
118-119: docker compose 명령어 실행 시 환경 변수 설정 방식 정리.현재 Line 119에서:
OWNER_LOWERCASE=$OWNER_LOWERCASE IMAGE_TAG=$IMAGE_TAG_ONLY docker compose -f docker-compose.dev.yml up -d이 패턴은 작동하지만,
OWNER_LOWERCASE가 Line 95에서 이미 export되었다면 불필요한 중복입니다. 일관성을 위해 다음 중 하나로 정리하세요:옵션 1: 환경 변수를 명시적으로 선언하고 재사용
export OWNER_LOWERCASE=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]') export IMAGE_TAG_ONLY=${{ steps.image_meta.outputs.image_tag }} # ... docker compose -f docker-compose.dev.yml up -d옵션 2: 매번 인라인으로 설정 (현재 방식이지만 정리)
IMAGE_TAG=${{ steps.image_meta.outputs.image_tag }} \ OWNER_LOWERCASE=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]') \ docker compose -f docker-compose.dev.yml up -d
129-132: 오래된 이미지 정리 로직이 정상 작동하는지 검증 권장.Line 129-132의 이미지 정리 로직은 수동으로 태그를 정렬하고 삭제합니다:
docker images "${IMAGE_NAME_BASE}" --format "{{.Tag}}" | \ sort -r | \ tail -n +6 | \ xargs -I {} docker rmi "${IMAGE_NAME_BASE}:{}" || true주의할 점:
docker images출력에<none>태그가 포함될 수 있으며, 이는 정렬 순서에 영향을 미칠 수 있습니다.- 태그가 6개 미만이면 아무것도 삭제되지 않습니다 (의도한 동작이라면 문제 없음).
|| true로 인해 삭제 실패가 무시되므로, 실제 오류를 인지하기 어려울 수 있습니다.개선 제안:
GHCR의 자동 정리 정책(Line 137-147, 최신 5개 유지)과의 일관성을 위해, 로컬 환경에서도 같은 개수를 유지하되, 더 명확한 로직을 고려하세요:
docker images "${IMAGE_NAME_BASE}" --format "table {{.Repository}}:{{.Tag}}\t{{.CreatedAt}}" | \ tail -n +2 | \ sort -k2 -r | \ tail -n +6 | \ awk '{print $1}' | \ xargs -r docker rmi또는 snok/container-retention-policy 같은 로컬 도구도 검토해볼 가치가 있습니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
.github/workflows/dev-cd.yml(2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-10T01:55:03.812Z
Learnt from: Hexeong
Repo: solid-connection/solid-connect-server PR: 552
File: .github/workflows/prod-cd.yml:40-45
Timestamp: 2025-11-10T01:55:03.812Z
Learning: GHCR (GitHub Container Registry)에서는 docker login 시 사용자명의 대소문자를 구분하지 않으며, 레지스트리 경로명은 항상 소문자로 정규화됩니다. 따라서 `github.repository_owner`를 그대로 사용해도 이미지 경로와의 대소문자 불일치 문제가 발생하지 않습니다.
Applied to files:
.github/workflows/dev-cd.yml
🔇 Additional comments (2)
.github/workflows/dev-cd.yml (2)
47-55: 이미지 메타데이터 정의 로직이 명확하고 효율적입니다.이미지 이름과 태그를 GitHub Actions Output으로 미리 정의하여 여러 단계에서 재사용할 수 있게 설계된 점이 좋습니다. 특히:
- OWNER_LOWERCASE로 소문자 정규화: GHCR 이미지명 규칙 준수 ✓
- 타임스탬프 기반 태깅(YYYYMMDD-HHMMSS): 버전 추적 명확함 ✓
- 이미지명 포맷 표준화: 코드 가독성 향상 ✓
137-147: GHCR 자동 정리 정책이 체계적으로 구성되었습니다.snok/container-retention-policy를 활용한 정책이 명확합니다:
- 태그 없는 이미지 자동 삭제 (delete-untagged: true)
- 최신 5개 버전 유지 (keep-n-tags: 5)
- 7일 이상 오래된 버전 정리 (cut-off: 7 days ago)
- 성공 시에만 실행 (if: success()) — 안정성 고려 ✓
로컬 정리 정책(Line 129-132)과도 일관성이 있어, 스토리지 관리가 예측 가능합니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
.github/workflows/dev-cd.yml (1)
137-147: GHCR 이미지 정리 정책과 로컬 호스트 정리 정책의 일관성이 확인됩니다.GHCR에서 최신 5개 태그를 유지(
keep-n-tags: 5)하고, Line 131에서 로컬 호스트에서도 동일하게 최신 5개를 유지하는 방식으로 정책이 일관되어 있습니다.delete-untagged: true로 미태그 이미지도 정리하므로 레지스트리 저장소 효율이 좋습니다.다만, 다음 사항을 확인해주세요:
- 정기적 정리 스케줄: 현재 구조에서는 성공적인 배포 시에만 정리가 실행됩니다(
if: success()). 배포가 자주 이루어지지 않는 기간이 있다면 저장소가 누적될 수 있으니, 필요시 별도의 정기 정리 워크플로우(예: 주 1회 스케줄 실행)도 고려해보세요.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
.github/workflows/dev-cd.yml(2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-10T01:55:03.812Z
Learnt from: Hexeong
Repo: solid-connection/solid-connect-server PR: 552
File: .github/workflows/prod-cd.yml:40-45
Timestamp: 2025-11-10T01:55:03.812Z
Learning: GHCR (GitHub Container Registry)에서는 docker login 시 사용자명의 대소문자를 구분하지 않으며, 레지스트리 경로명은 항상 소문자로 정규화됩니다. 따라서 `github.repository_owner`를 그대로 사용해도 이미지 경로와의 대소문자 불일치 문제가 발생하지 않습니다.
Applied to files:
.github/workflows/dev-cd.yml
🔇 Additional comments (3)
.github/workflows/dev-cd.yml (3)
47-67: 이미지 메타데이터 정의 및 빌드 캐시 전략이 명확합니다.이미지명과 태그를 명시적으로 정의하고, Docker BuildX의 레지스트리 캐시(
type=registry)를 활용해 빌드 성능을 개선하는 구조가 좋습니다. 타임스탬프 기반 태그(YYYYMMDD-HHMMSS)는 dev 환경에서 이미지 버전 추적에 효과적입니다.
87-135: SSH 배포 스크립트의 변수 관리와 함께 일관성 개선을 제안합니다.현재 구조는 다음과 같은 점에서 정상 작동하지만, 명확성을 위해 몇 가지 정리를 제안합니다:
로그인 사용자명 일관성
- Line 95에서
OWNER_LOWERCASE를 계산하지만, Line 100의docker login에서는 여전히${{ github.repository_owner }}를 사용 중입니다.- 비록 GHCR에서 대소문자를 구분하지 않지만, 코드의 일관성과 가독성 차원에서 이미 계산한
OWNER_LOWERCASE변수를 사용하는 것이 좋습니다.환경 변수 전달 방식
- Line 119의
IMAGE_TAG=$IMAGE_TAG_ONLY docker compose ...는 정상 작동합니다(IMAGE_TAG환경변수가 해당 명령 실행 시에만 유효).- 다만,
OWNER_LOWERCASE는 Line 95에서 이미 export되었으므로, docker-compose.dev.yml이 두 변수를 모두 필요로 한다면 현재 구조로 충분합니다.오래된 이미지 정리 로직 확인
- Lines 129-132에서
sort -r | tail -n +6으로 최신 5개를 제외한 나머지를 삭제하는 로직은 정확합니다.- 다만, 타임스탬프 기반 정렬(이미지 태그 문자열)과 실제 생성 시간의 순서가 일치하는지 확인이 필요합니다. (현재 YYYYMMDD-HHMMSS 형식이므로 문자열 정렬과 시간 순서가 일치함)
다음 개선안을 고려해주세요:
# 2. 서버가 GHCR에 로그인 (pull 받기 위해) - echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.repository_owner }} --password-stdin + echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${OWNER_LOWERCASE} --password-stdin이렇게 하면 로그인 사용자명이 이미지명 계산 부분과 완전히 일치하게 됩니다.
69-80: 설정 파일 전송 단계가 효율적으로 통합되었습니다.기존의 개별 파일 전송 방식에서 하나의 scp 명령으로 여러 파일을 전송하도록 통합되어, 워크플로우 단계가 간결해졌습니다. SSH 보안 설정(StrictHostKeyChecking=no, 권한 600)도 적절합니다.
lsy1307
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
개인적으로 on push 방식으로 release태그를 사용하는 게 배포 자동화 면에서 이점이 있다고 생각합니당
.github/workflows/dev-cd.yml
Outdated
| echo "${{ secrets.DEV_PRIVATE_KEY }}" > deploy_key_ssh.pem | ||
| chmod 600 deploy_key_ssh.pem |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
위에서 생성한 key를 그대로 사용해도 되지 않나요..?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
해당 내용 반영했습니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이름도 바꿔주셔야 할 것 같아요! deploy_key.pem으로 저장이 되었는데 deploy_key_ssh.pem을 사용하고 있습니당
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
반영했습니다!
.github/workflows/dev-cd.yml
Outdated
| export FULL_IMAGE_NAME="ghcr.io/${OWNER_LOWERCASE}/solid-connection-dev:${IMAGE_TAG_ONLY}" | ||
| # 2. 서버가 GHCR에 로그인 (pull 받기 위해) | ||
| echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.repository_owner }} --password-stdin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
지금 쓰기가 가능한 토큰이 서버로 전송되는데 보안상 취약하지 않을까요...? 읽기 전용 토큰을 따로 발급해서 사용하는 게 좋아보입니당
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SSH를 통해 GHCR에 접근하는 이 방식을 적용하려면, SUBMODULE_ACCESS_TOKEN처럼 Fine-grained Token을 사용하는 것이 보안상 가장 좋다고 생각합니다!
하지만 이 방식을 사용하려면 GHCR 읽기 권한이 있는 분이 직접 토큰을 발급해야 하는데, 이는 특정 계정에 파이프라인이 의존하게 되는 문제가 있어 망설여졌습니다.
그래서 일단은 임시로 GITHUB_TOKEN을 사용하는 방식을 적용했습니다만, 혹시 이 '개인 종속성' 문제를 해결할 더 좋은 방법이 있다면 의견 부탁드립니다! @lsy1307
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
machine user 개념으로 CI/CD용 계정을 따로 만들어서 사용하는 건 어떨까요? Github Docs에도 나와있는 내용입니다!
참고 : https://docs.github.com/en/get-started/learning-about-github/types-of-github-accounts#user-accounts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
machine user 대신 최근 Github 추천하는 방식인 Github App을 사용해서 Repository에서 임시 토큰을 발급할 수 있도록 개선했습니다! 해당 문제는 해결된 것 같아요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
.github/workflows/dev-cd.yml (1)
83-132: SSH 스크립트 내 환경 변수 정의 정리 제안.현재 설계:
- 라인 52–55에서 GitHub Actions 컨텍스트에서
OWNER_LOWERCASE와IMAGE_TAG생성- 라인 92–94에서 SSH 스크립트 내부에서 동일한 값을 재계산
재계산은 작동하지만 불필요한 중복입니다. GitHub Actions 출력값이 이미 SSH 스크립트 내
${{ steps.image_meta.outputs.* }}구문으로 전달되므로, 아래처럼 간소화할 수 있습니다:export OWNER_LOWERCASE=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]') export IMAGE_TAG_ONLY=${{ steps.image_meta.outputs.image_tag }} export FULL_IMAGE_NAME="ghcr.io/${OWNER_LOWERCASE}/solid-connection-dev:${IMAGE_TAG_ONLY}"이미 export된
OWNER_LOWERCASE를 재계산할 필요 없이 일관성 있게 사용할 수 있으며, 라인 116의IMAGE_TAG=$IMAGE_TAG_ONLY docker compose...부분도 명확해집니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
.github/workflows/dev-cd.yml(2 hunks)src/main/resources/secret(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- src/main/resources/secret
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-10T01:55:03.812Z
Learnt from: Hexeong
Repo: solid-connection/solid-connect-server PR: 552
File: .github/workflows/prod-cd.yml:40-45
Timestamp: 2025-11-10T01:55:03.812Z
Learning: GHCR (GitHub Container Registry)에서는 docker login 시 사용자명의 대소문자를 구분하지 않으며, 레지스트리 경로명은 항상 소문자로 정규화됩니다. 따라서 `github.repository_owner`를 그대로 사용해도 이미지 경로와의 대소문자 불일치 문제가 발생하지 않습니다.
Applied to files:
.github/workflows/dev-cd.yml
🔇 Additional comments (4)
.github/workflows/dev-cd.yml (4)
11-33: 좋은 권한 설정과 표준 Gradle 스택.권한에
packages: write를 추가했고, 최신 공식 Gradle 액션(v3)을 사용하여 정확하게 구성되었습니다. JDK 17 temurin 배포판도 Dockerfile 변경과 일치합니다.
35-67: Docker 빌드·푸시 단계가 잘 설계됨.Docker Buildx 멀티 아키텍처 지원, GHCR 로그인, 이미지 메타데이터(이름·태그) 사전 정의, 레지스트리 캐시 전략까지 모두 CD 성능 개선 목표와 일치합니다. 특히 buildcache 태그를 활용한 레이어 캐싱은 반복 배포 시 빌드 시간 단축에 효과적입니다.
103-132: 원격 배포 및 정리 로직이 효율적으로 구성됨.다음 항목들이 잘 구성되었습니다:
- Config 파일 재배치: Nginx 설정을 정확한 경로(
/etc/nginx/conf.d/default.conf)로 이동- Nginx 검증 및 재시작:
nginx -t로 사전 검증 후 재시작 (무중단 배포)- Docker Compose 재시작:
down→up -d로 깔끔한 순환- 이미지 정리:
docker image prune -f로 이미지 제거 및 로컬 태그 이미지 최신 5개 유지- GHCR 정리: snok/container-retention-policy로 오래된 이미지 자동 삭제
특히 로컬(라인 122–129)과 GHCR(라인 135–144) 양쪽에서 정리 정책을 일관되게 적용(최신 5개 유지)하는 것이 스토리지 효율성과 유지보수성 면에서 좋습니다.
70-81: Deploy 키 파일명 오류.라인 72에서
deploy_key.pem을 생성하고 있으나, 라인 85의 SSH 명령어에서deploy_key_ssh.pem을 참조하고 있습니다. 이는 파일을 찾을 수 없는 오류로 인해 배포가 실패합니다.라인 85를 다음과 같이 수정하세요:
- ssh -i deploy_key_ssh.pem \ + ssh -i deploy_key.pem \Likely an incorrect or invalid review comment.
whqtker
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
제가 남긴 리뷰들에 대해서 해소가 되어서 approve하겠습니다 !
다른 분들까지 approve되면 머지 진행해주시면 될 거 같습니다. 고생하셨어요 !!
…ening-cd-time # Conflicts: # src/main/resources/secret
* fix: yml 들여쓰기 수정 (#555) * fix: yml 들여쓰기 수정 * fix: jdk 변경 * refactor: 멘토 및 채팅 관련 API 응답 수정 (#537) * refactor: 멘토의 멘토링 조회 응답에서 mentoringId가 아니라 roomId를 포함하도록 * refactor: 파트너가 멘토인 경우 partnerId는 mentorId로 - AS IS: 멘토/멘티 모두 partnerId가 siteUserId - TO BE: 멘티: siteUserId, 멘토: mentorId * refactor: 응답의 senderId가 mentorId/siteUserId가 되도록 * refactor: senderId에 해당하는 chatParticipant가 없을 경우 예외 처리하는 로직 추가 * refactor: 메서드명에 맞게 시그니처 변경 * refactor: getChatMessages 메서드에서 응답으로 siteUserId를 넘겨주도록 - AS IS: mentorId(mentor) / siteUserId(mentee) - TO BE: siteUserId(all) * refactor: 헬퍼 메서드로 메서드 복잡성을 분산한다 * refactor: getChatPartner 메서드의 응답으로 siteUserId를 넘겨주도록 - AS IS: mentorId(mentor) / siteUserId(mentee) - TO BE: siteUserId(all) * refactor: CD 성능 개선 (#552) * fix: deprecated된 base image를 eclipse-temurin:17-jdk로 변경 * refactor: scp 파일 전송하는 방식에서 GHCR로 push/pull하도록 변경 * fix: GHCR image 제거시 Org의 GITHUB_TOKEN 사용하도록 변경 * refactor : scp 파일 전송하는 방식에서 GHCR로 push/pull하도록 prod-cd.yml과 docker-compose.prod.yml 변경 * fix: prod 인스턴스 old image 이름 통일 * fix: prod-cd.yml StrictHostKeyChecking 옵션 문법 오류 수정 * fix: prod-cd.yml StrictHostKeyChecking 옵션 문법 오류 수정 * fix: dev-cd.yml Old images 정리 작업 중 이미지 이름 불일치 문제 해결 * chore: 마지막 줄 개행 추가 * chore: 마지막 줄 개행 추가 * feat: stage 인스턴스에 대한 최신 이미지 5개 유지 기능 및 old 이미지 제거 기능 추가 * chore: 중복된 환경변수 지정 제거 * chore: 중복된 pem키 생성 로직 제거 * fix: 잘못된 pem키 이름 수정 * refactor: 원격 호스트에서 pull할 경우, 최소 권한으로 실행하도록 Github App으로 임시토큰 발급하도록 수정 * fix: Github App이 발행한 임시 토큰에 대해 읽기 권한 명시 (#565) * fix: GitHub app token permission 문제 해결 (#566) * fix: Github App이 발행한 임시 토큰에 대해 읽기 권한 명시 * fix: Github App이 발행한 임시 토큰에 대해 읽기 권한 명시 문법 오류 수정 * fix: Github App이 발행한 임시 토큰에 대해 읽기 권한 명시 문법 오류 수정 * fix: Github App이 발행한 임시 토큰에 대해 Contents 읽기 권한 추가 * fix: GitHub app token permission 문제 오류 해결 (#567) * fix: Github App이 발행한 임시 토큰에 대해 읽기 권한 명시 * fix: Github App이 발행한 임시 토큰에 대해 읽기 권한 명시 문법 오류 수정 * fix: Github App이 발행한 임시 토큰에 대해 읽기 권한 명시 문법 오류 수정 * fix: Github App이 발행한 임시 토큰에 대해 Contents 읽기 권한 추가 * fix: Github App이 발행한 임시 토큰에 대해 조직 레벨에서 읽기 권한 추가 * fix: GitHub app token permission이 repo 레벨에서 부여되는 문제 해결 (#568) * fix: Github App이 발행한 임시 토큰에 대해 읽기 권한 명시 * fix: Github App이 발행한 임시 토큰에 대해 읽기 권한 명시 문법 오류 수정 * fix: Github App이 발행한 임시 토큰에 대해 읽기 권한 명시 문법 오류 수정 * fix: Github App이 발행한 임시 토큰에 대해 Contents 읽기 권한 추가 * fix: Github App이 발행한 임시 토큰에 대해 조직 레벨에서 읽기 권한 추가 * fix: Github App이 발행한 임시 토큰에 대해 조직 레벨에서 읽기 권한 추가 * fix: GitHub app token permission 권한 오류 해결 (#569) * fix: Github App이 발행한 임시 토큰에 대해 읽기 권한 명시 * fix: Github App이 발행한 임시 토큰에 대해 읽기 권한 명시 문법 오류 수정 * fix: Github App이 발행한 임시 토큰에 대해 읽기 권한 명시 문법 오류 수정 * fix: Github App이 발행한 임시 토큰에 대해 Contents 읽기 권한 추가 * fix: Github App이 발행한 임시 토큰에 대해 조직 레벨에서 읽기 권한 추가 * fix: Github App이 발행한 임시 토큰에 대해 조직 레벨에서 읽기 권한 추가 * fix: Github App이 발행한 임시 토큰에 대해 조직 레벨에서 읽기 권한 추가 * test: fork repo의 작업 branch에서 해당 workflows가 실행되도록 임시 수정 * refactor: test용 설정 제거 * feat: claude.md 파일 추가 (#560) * fix : 동일 멘토 멘티 중복 신청 불가능하도록 수정 (#563) * fix : 동일 멘토 멘티 중복 신청 불가능하도록 수정 - UK 제약조건 추가 - flyway script 추가 - CustomException 추가 - Service 로직 수정 - Test code 추가 * fix : column명 오류 수정 - column명 camelCase -> snake_case로 변경 * fix : column명 오류 수정 - column명 name으로 명시 * fix: GitHub app token permission 권한 오류 해결 (#570) * fix: Github App이 발행한 임시 토큰에 대해 읽기 권한 명시 * fix: Github App이 발행한 임시 토큰에 대해 읽기 권한 명시 문법 오류 수정 * fix: Github App이 발행한 임시 토큰에 대해 읽기 권한 명시 문법 오류 수정 * fix: Github App이 발행한 임시 토큰에 대해 Contents 읽기 권한 추가 * fix: Github App이 발행한 임시 토큰에 대해 조직 레벨에서 읽기 권한 추가 * fix: Github App이 발행한 임시 토큰에 대해 조직 레벨에서 읽기 권한 추가 * fix: Github App이 발행한 임시 토큰에 대해 조직 레벨에서 읽기 권한 추가 * test: fork repo의 작업 branch에서 해당 workflows가 실행되도록 임시 수정 * refactor: test용 설정 제거 * fix: docker login username 불일치 문제 * refactor: 최소권한 원칙 적용을 위한 Action Job 분리 * refactor: 필요없는 주석 제거 * fix: GHCR 정리 권한 PAT로 해결 (#573) * feat: 지원서가 APPROVED 인 유저의 멘토 생성 기능 추가 (#562) * feat: 지원서가 APPROVED 인 유저의 멘토 생성 기능 추가 * refactor: submitMentorApplication 메서드의 멘토 지원 유효 검증 부분을 메서드로 추출 * refactor: MentorMyPage 생성, 수정 부분의 channel 생성, 업데이트 부분 중복 제거 * test: Mentor 생성 관련 테스트 추가 * fix: 코드래빗 리뷰 적용 * refactor: 멘토 생성 시 channelRequest가 null 일 떄 예외 처리 * feat: MentorApplicationRequest 필드에 유효성 어노테이션 추가 * test: 채널 검색 시 siteUserId로 조회하는 문제 해결 * fix: 리뷰 수정사항 적용 * fix: 파일 끝에 개행 추가 * refactor: 멘토 생성 메서드에서 siteUser의 검증 제외 * refactor: dto 단에서 채널 리스트 null 검증 * feat: MentorApplication에 termId 추가 flyway 스크립트 추가 * fix: flyway 버전 충돌 해결 * feat: 어드민 멘토 승격 요청 페이징 조회 기능 추가 (#576) * feat: 어드민 멘토 지원서 페이징 조회 기능 추가 * feat: mentor/repository 패키지에 custom 패키지 추가 - custom 패키지에 페이징 조회를 책임지는 MentorApplicationFilterRepository 추가 - MentorApplicationSearchCondition 에서 넘긴 keyword 기반으로 닉네임, 권역, 나라, 학교명으로 필터링 검색 기능 추가 - MentorApplicationSearchCondition 에서 넘긴 mentorApplicationStatus 기반으로 승인, 거절, 진행중 으로 필터링 기능 추가 * test: 어드민 멘토 지원서 페이징 조회 테스트 추가 * feat: MentorApplication 엔티티에 approved_at 필드 추가 flyway 스크립트 작성 * fix: 파일 끝에 개행 추가 * refactor: 페이징 조회 시 count 쿼리에 불필요한 조인 막기 * fix: 코드래빗 리뷰 적용 * fix: flyway V39 스크립트 파일명 수정 * test: 테스트 코드 오류 수정, 검증 추가 * test: 기대하는 값이랑 다른 테스트 응답을 수정합니다 * feat: 어드민 멘토 승격 지원서 승인/거절 기능, 상태 별 지원서 개수 조회 기능 추가 (#577) * feat: 어드민 멘토 승격 지원서 승인/거절 기능 추가 * test: 어드민 멘토 지원서 승인/거절 테스트 추가 * feat: 멘토 지원서 상태별 개수 조회 기능 추가 * test: 멘토 지원서 상태별 개수 조회 테스트 추가 * fix: 대학이 선택되지 않은 멘토 지원서 승인 시 예외 발생하도록 수정 * refactor: 리뷰 내용 반영 * refactor: MENTOR_APPLICATION_ALREADY_CONFIRM -> MENTOR_APPLICATION_ALREADY_CONFIRMED 로 수정 * refactor: 멘토 지원서 거절 사유 관련하여 기획에 명시되지 않은 길이 제한 제거 * refactor: 리뷰 적용 * refactor: 변수명, 필드명 일관성 맞추기 * test: assertAll 적용 * feat: region 관련 관리 기능 추가 (#561) * feat: 지역 생성 기능 구현 (AdminRegion) 지역을 생성하는 기능을 구현했습니다: - AdminRegionCreateRequest: 지역 생성 요청 DTO - AdminRegionResponse: 지역 응답 DTO - AdminRegionService.createRegion(): 중복 검사를 포함한 지역 생성 로직 - AdminRegionController.createRegion(): HTTP POST 엔드포인트 중복 검사: - 지역 코드 중복 확인 - 한글명 중복 확인 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * feat: 지역 수정/삭제/조회 기능 구현 및 테스트 추가 (AdminRegion) 지역 관리 기능을 완성했습니다: 구현 기능: - AdminRegionUpdateRequest: 지역 수정 요청 DTO - AdminRegionService.updateRegion(): 한글명 중복 검사를 포함한 지역 수정 - AdminRegionService.deleteRegion(): 지역 삭제 - AdminRegionService.getAllRegions(): 전체 지역 조회 - AdminRegionController: 수정/삭제/조회 HTTP 엔드포인트 테스트 코드 (AdminRegionServiceTest): - CREATE: 정상 생성, 코드 중복, 한글명 중복 테스트 - UPDATE: 정상 수정, NOT_FOUND, 중복 한글명, 동일 한글명 테스트 - DELETE: 정상 삭제, NOT_FOUND 테스트 - READ: 빈 목록, 전체 조회 테스트 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * fix: 지역 관리 관련 에러코드 추가 (ErrorCode) 지역 관리 기능에 필요한 에러코드를 추가했습니다: - REGION_NOT_FOUND: 존재하지 않는 지역 - REGION_ALREADY_EXISTS: 이미 존재하는 지역 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * fix: jpa 오류 수정 * refactor: 코드리뷰 반영 --------- Co-authored-by: Claude <[email protected]> * fix: config.alloy 파일 경로 불일치 문제 해결 (#586) * fix: config.alloy 파일 경로 불일치 문제 해결 * refactor: docker-compose를 수정하는게 아닌 cd.yml의 경로를 수정하여 해결 * feat: 소셜 로그인 사용자는 비밀번호 변경을 할 수 없다. (#582) * feat: 소셜 로그인 사용자는 비밀번호 변경을 할 수 없도록 * test: 소셜 로그인 사용자 비밀번호 변경 관련 테스트 코드 작성 * chore: 컨벤션에 맞게 메서드명 변경 - ~~ 예외가 발생한다 * chore: 충돌 해결 * fix: Upgrade 헤더 유무에 따라 Connection 헤더의 값을 동적으로 설정하도록 (#581) * fix: Upgrade 헤더 유무에 따라 Connection 헤더의 값을 동적으로 설정하도록 - Upgrade 헤더가 존재하면(e.g. WebSocket) upgrade로 설정 - Upgrade 헤더가 존재하지 않으면 keep-alive로 설정 * chore: 서브모듈 업데이트 * feat: 멘토 지원서 대학교 매핑 기능, 대학 선택 상태 페이징 조건 추가 (#583) * feat: 멘토 지원서 검색 조건에 UniversitySelectType 추가 * feat: 어드민 멘토 지원서 페이징 조회 응답에 UniversitySelectType 추가 * test: 멘토 지원서 조회 테스트 추가 - test: UniversitySelectType 기반 페이징 조회 테스트 추가 * feat: 멘토 지원서에 대학 매핑 기능 추가 * test: 멘토 지원서 대학 매핑 테스트 추가 * refactor: 의미 없는 import 제거 * refactor: 리뷰 내용 반영 * refactor: 개행 및 공백 추가 * refactor: pathVariable 네이밍을 kebab-case 로 통일 * refactor: Service 레이어의 검증 로직을 도메인으로 이동 * refactor: PENDING 상태 및 OTHER 타입 검증을 도메인 메서드로 관리 * refactor: assignUniversity() 호출 전 검증 책임을 도메인 엔티티에 위임 * test : assertAll 로 검증 그룹화 * refactor: 스프링 부트 앱 외의 사이드 인프라 배포 과정을 분리 (#592) * refactor: dev 환경에서의 side-infra 배포 과정 분리 * refactor: prod 환경에서의 side-infra 배포 과정 분리 * refactor: docker-compose 가 실행되고 있지 않아도 스크립트가 실패하지 않게 변경 * fix: docker compose up 시에 사용할 환경변수 중 누락된 변수를 추가 * fix: S3 이름 불일치 문제 해결 (#594) * fix: s3 이름 불일치 문제 해결 * fix: s3와의 연동된 cloudfront URL로 수정 * refactor: 분리한 사이드 인프라에 대해서 필요없는 파일 정리 (#596) * test: flyway 스크립트를 검증하는 테스트 코드 작성 (#588) * test: flyway 스크립트를 검증하는 테스트 코드 작성 * fix: DirtiesContext 어노테이션을 통해 기존 컨텍스트를 폐기하도록 - 새로운 MySQL 환경에서 마이그레이션이 이루어지도록 수정 * fix: flyway 검증용의 별도의 MySQL 컨테이너를 사용하도록 * chore: 테스트 의도를 쉽게 이해할 수 있도록 주석 추가 * chore: 명시적으로 컨테이너를 시작하도록 - 또한 MySQLTestContainer 코드와 유사한 컨벤션을 가지도록 수정 * refactor: 게시글 조회 응답에 댓글 deprecated 여부 포함하도록 (#599) * feat: 유저의 멘토 지원서 신청 이력 조회 기능 추가 (#603) * feat: 유저의 멘토 지원 이력 조회 기능 추가 * refactor: 매개변수 타입 통일 * refactor: long 타입을 Long 으로 수정 * test: 멘토 지원서 이력 조회 테스트 추가 * test: MentorApplicationFixtureBuilder 에 rejectedReason 필드 및 빌더 메서드 추가 * refactor: 리뷰 사항 적용 * test: 멘토 지원서 이력 조회 에서 user와 university 재사용 * refactor: 긴 uri 를 짧게 수정 * refactor: 서브모듈 해시값 되돌리기 * refactor: 개행 지우기 * refactor: applicationOrder 자료형을 long 으로 수정 * fix: applicationOrder 를 int 자료형으로 처리하도록 복구 - 순서를 나타내고, 해당 값이 21억을 넘길 수 없다 판단하여 더 적합한 int 자료형으로 복구 * test: long type 을 기대하던 테스트 에러 해결 * fix: 탈퇴한 사용자가 물리적 삭제가 되지 않았던 문제를 해결한다 (#574) * refactor: FK에 ON DELETE CASCADE 옵션 추가 * refactor: 삭제 메서드로 사용자 연관 데이터를 삭제하도록 * feat: 어드민 유저 차단 기능 추가 (#604) * feat: 어드민 차단 기능 * test: 어드민 차단 기능 * feat: API 성능 로깅, 쿼리 별 메트릭 전송 추가 (#602) * feat: HTTP 요청/응답 로깅 필터 구현 - traceId 기반 요청 추적 - 요청/응답 로깅 - CustomExceptionHandler와 중복 로깅 방지 - Actuator 엔드포인트 로깅 제외 * feat: ExceptionHandler에 중복 로깅 방지 플래그 및 userId 로깅 추가 * feat: API 수행시간 로깅 인터셉터 추가 * feat: ApiPerf 인터셉터, Logging 필터 빈 등록 * refactor: logback 설정 변경 - info, warn, error, api_perf 로 로그 파일 분리해서 관리 * feat: 쿼리 별 수행시간 메트릭 모니터링 추가 * feat: 데이터소스 프록시 의존성 및 config 파일 추가 * feat: 데이터 소스 프록시가 metric을 찍을 수 있도록 listener 클래스 추가 * feat: 요청 시 method, uri 정보를 listener에서 활용하기 위해 RequestContext 및 관련 interceptor 추가 * refactor: 비효율적인 Time 빌더 생성 개선 - Time.builder 를 사용하면 매번 빌더를 생성하여 비효율적인 문제를 meterRegistry.timer 방식으로 해결 * feat: 로깅을 위해 HttpServeletRequest 속성에 userId 추가 * refactor: logback 설정 중 local은 console만 찍도록 수정 * refactor: FILE_PATTERN -> LOG_PATTERN 으로 수정 * test: TokenAuthenticationFilter에서 request에 userId 설정 검증 추가 - principal 조회 예외를 막기 위해 siteUserDetailsService given 추가 * refacotr: 코드 래빗 리뷰사항 반영 * test: 중복되는 테스트 제거 * refactor: 사용하지 않는 필드 제거 * refactor: 리뷰 내용 반영 * refactor: ApiPerformanceInterceptor에서 uri 정규화 관련 코드 제거 * refactor: ApiPerformanceInterceptor에서 if-return 문을 if-else 문으로 수정 * refactor: 추가한 interceptor 의 설정에 actuator 경로 무시하도록 셋팅 * refactor: 중복되는 의존성 제거 * refactor: 로깅 시 민감한 쿼리 파라미터 마스킹 - EXCLUDE_QUERIES 에 해당하는 쿼리 파라미터 KEY 값의 VALUE 를 masking 값으로 치환 * refactor: 예외 처리 후에도 Response 로그 찍도록 수정 * refactor: CustomExceptionHandler 원상복구 - Response 로그를 통해 user를 추적할 수 있으므로 로그에 userId 를 추가하지 않습니다 * refactor: 리뷰 사항 반영 * refactor: RequestContext 빌더 제거 * refactor: RequestContextInterceptor import 수정 * refactor: logback yml 파일에서 timestamp 서버 시간과 동일한 규격으로 수정 * refactor: ApiPerformanceInterceptor 에서 동일 내용 로그 중복으로 찍는 문제 수정 * fix: decode를 두 번 하는 문제 수정 * test: 로깅 관련 filter, interceptor 테스트 추가 * refactor: 코드래빗 리뷰사항 반영 * test: contains 로 비교하던 검증 로직을 isEqualTo 로 수정 * test: preHandle 테스트 에서 result 값을 항상 검증 * refactor: 단위테스트에 TestContainer 어노테이션 제거 * fix: conflict 해결 * fix: docker-compose 충돌 해결 (#610) * chore: release github action 임의 실행 추가 * refactor: 기본 추천 대학 후보 추가 (#161) * fix: config.alloy 경로 수정 * hotfix: 모의지원 현황 어드민 권한 제거 * hotfix: import 제거 * chore: 서브모듈 해시 업데이트 (#611)


관련 이슈
작업 내용
jar파일을 포함,nginx와alloy등의 설정 파일을ssh copy(scp)명령으로 전송 이후, 원격 호스트에서build하고docker-compose를 실행하는 방식을 사용해왔습니다.GHCR(Github Container Registry)를 사용하여 Github Action에서 이미지 빌드 이후,GHCR로 push/원격호스트에서 pull하는 방식으로docker-compose를 실행하도록 리팩토링했습니다.3분이었지만, 현재는 평균2분 15초로25%단축시킨 결과가 나왔습니다. (테스트 결과는 아래 첨부파일에 올려두겠습니다.)이미지:날짜-시간방식으로 태그가 되어 있는 상태입니다. 하지만 prod 인스턴스는 릴리즈 버전으로 관리될 수 있기에 여러분의 의견을 듣고 내용 반영하여 추가 commit 올리겠습니다!특이 사항
base image로openjdk:17-jdk를 사용해왔지만, 해당 base image가 deprecated되어 공식 대체 이미지인eclipse-temurin:17-jdk로 변경하였습니다.리뷰 요구사항 (선택)
날짜-시간으로 설정해두었습니다.첨부파일(테스트 결과)